﻿/*-----------------------------------------------------------------------------------------------
// Copyright (C) 2016 华跃博弈科技有限公司 
//
// 文件名：        BaseRepository.cs
// 文件功能描述：   数据持久层基类，所有数据持久层子类必须继承该类
//
// 
// 创建标识：       庞永飞  2016-04-17
//
// 修改标识：
// 修改描述：
//
// 备注：	
// 				
//-----------------------------------------------------------------------------------------------*/

using HYBY.Task.DataEntity;
using HYBY.Task.Repository.Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;


namespace HYBY.Task.Repository {
  
  public abstract class BaseRepository<TEntity> : IRepository<TEntity>, IDisposable 
    where TEntity : BaseEntity,new() {

    #region 构造器

    public BaseRepository() {

    }

    #endregion

    #region 公共方法

    /// <summary>
    /// 根据主键获取实体
    /// </summary>
    /// <param name="Id">主键ID</param>
    /// <returns>具体实体对象实例</returns>
    public virtual TEntity Get(object Id) {
      return DapperUtil.QueryByIdentity<TEntity>(Id);
    }

    /// <summary>
    /// 保存实体对象到持久化存储
    /// </summary>
    /// <param name="entity">实体对象实例</param>
    /// <returns>成功返回true否则返回false</returns>
    public abstract bool Save(TEntity entity);

    /// <summary>
    /// 从持久化存储器中删除实体对象
    /// </summary>
    /// <param name="entity">实体对象实例</param>
    /// <returns>成功返回true否则返回false</returns>
    public abstract bool Delete(TEntity entity);

    /// <summary>
    /// 执行逻辑删除
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    public bool LogicalDelete(TEntity entity) {
      return false;
    }

    #endregion

    #region 受保护方法

    /// <summary>
    /// 根据主键查询对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="pk"></param>
    /// <returns></returns>
    protected T QueryByIdentity<T>(object pk) where T : class {
      return DapperUtil.QueryByIdentity<T>(pk);
    }
    
    /// <summary>
    /// 根据匿名参数查询单个对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="anonymousParm"></param>
    /// <returns></returns>
    protected T QueryByParm<T>(object anonymousParm) where T : class {
      return DapperUtil.QueryByParm<T>(anonymousParm);
    }

    /// <summary>
    /// 更新对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="model"></param>
    /// <returns></returns>
    protected bool Update<T>(T model) where T : class {
      return DapperUtil.Update<T>(model);
    }

    /// <summary>
    /// 写入对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="model"></param>
    /// <param name="isGenKey">true获得自动生成的主键  false 不会返回</param>
    /// <returns></returns>
    protected int Insert<T>(T model, bool isGenKey = false) where T : class {
      return DapperUtil.Insert<T>(model, isGenKey);
    }

    /// <summary>
    /// 更新部分值
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="parm"></param>
    /// <returns></returns>
    protected bool UpdatePColumn<T>(object parm) where T : class {
      return DapperUtil.UpdatePartialColumns<T>(parm);
    }

    /// <summary>
    /// 执行存储过程
    /// </summary>
    /// <param name="statementId"></param>
    /// <param name="anonymousObject"></param>
    protected void ExecuteProcedure(string statementId, object anonymousObject = null) {
      DapperUtil.ExecuteProcedure(statementId, anonymousObject);
    }

    /// <summary>
    /// 执行存储过程并返回值
    /// </summary>
    /// <param name="statementId"></param>
    /// <param name="returnValue">存储过程返回参数@returnValue</param>
    /// <param name="anonymousObject"></param>
    /// <returns></returns>
    protected string ExecuteProcedure(string statementId, string returnValue, object anonymousObject = null) {
      return DapperUtil.ExecuteProcedure(statementId, returnValue, anonymousObject);
    }

    /// <summary>
    /// 自定义多个查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="statementId"></param>
    /// <param name="parameter"></param>
    /// <returns></returns>
    protected IEnumerable<T> Query<T>(string statementId, object parameter = null) {
      return DapperUtil.Query<T>(statementId, parameter);
    }

    /// <summary>
    /// 自定义查询 带复杂条件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="statementId"></param>
    /// <param name="dictionary"></param>
    /// <param name="parameter"></param>
    /// <returns></returns>
    protected IEnumerable<T> Query<T>(string statementId, IDictionary<string, object> dictionary, object parameter = null) {
      return DapperUtil.Query<T>(statementId, dictionary, parameter);
    }

    /// <summary>
    /// 执行自定义SQL 用于 insert update delete
    /// </summary>
    /// <param name="statementId"></param>
    /// <param name="parameter"></param>
    /// <returns></returns>
    protected int Execute(string statementId, object parameter = null) {
      return DapperUtil.Execute(statementId, parameter);
    }

    protected int Execute(string statementId, IDictionary<string, object> dictionary, object parameter = null) {
      return DapperUtil.Execute(statementId, dictionary, parameter);
    }

    /// <summary>
    /// 存储过程分页
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="statementId">sql模板</param>
    /// <param name="pageNum">页码</param>
    /// <param name="pageSize">每页显示条数</param>
    /// <param name="totalRecord">总记录数</param>
    /// <param name="where">查询条件</param>
    /// <returns></returns>
    protected IEnumerable<T> QueryPageExecProcedure<T>(string statementId, int pageNum, int pageSize, out int totalRecord, string where = "") where T : class, new() {
      return DapperUtil.QueryPageExecProcedure<T>(statementId, pageNum, pageSize, out totalRecord, where);
    }

    /// <summary>
    /// 自定义分页查询
    /// </summary>
    /// <typeparam name="T">分页查询，此T需继承PagingEntityBase</typeparam>
    /// <param name="statementId">SQL ID</param>
    /// <param name="pageNum">当前页码</param>
    /// <param name="pageSize">每页显示条数</param>
    /// <param name="orderBy">排序条件如:CreateDate desc 多个用逗号分隔 如con1 desc,con2 asc</param>
    /// <param name="dictionary">复杂参数组合</param>
    /// <param name="parameter">查询参数</param>
    /// <returns></returns>
    protected IEnumerable<T> QueryPageing<T>(string statementId, int pageNum, int pageSize, string orderBy, IDictionary<string, object> dictionary = null, object parameter = null) where T : class, new() {
      return DapperUtil.QueryPageing<T>(statementId, pageNum, pageSize, orderBy, dictionary, parameter);
    }

    /// <summary>
    /// 执行存储过程 返回对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="statementId"></param>
    /// <param name="anonymousObject"></param>
    /// <returns></returns>
    protected T ExecuteProcedure<T>(string statementId, object anonymousObject = null) where T : class,new() {
      return DapperUtil.ExecuteProcedureModel<T>(statementId, anonymousObject);
    }

    /// <summary>
    /// 存储过程返回集合
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="statementId"></param>
    /// <param name="anonymousObject"></param>
    /// <returns></returns>
    protected IEnumerable<T> ExecuteProcedureIEnumerable<T>(string statementId, object anonymousObject = null) where T : class,new() {
      return DapperUtil.ExecuteProcedureIEnumerable<T>(statementId, anonymousObject);
    }

    #endregion

    #region 私有方法

    private DbType GetDbType(Type type) {
      if (type == typeof(String)) return DbType.String;
      if (type == typeof(Int16)) return DbType.Int16;
      if (type == typeof(Int32)) return DbType.Int32;
      if (type == typeof(Int64)) return DbType.Int64;
      if (type == typeof(Double)) return DbType.Double;
      if (type == typeof(Decimal)) return DbType.Decimal;
      if (type == typeof(Boolean)) return DbType.Boolean;
      if (type == typeof(Byte)) return DbType.Byte;
      if (type == typeof(DateTime)) return DbType.DateTime;
      if (type == typeof(UInt16)) return DbType.UInt16;
      if (type == typeof(UInt32)) return DbType.UInt32;
      if (type == typeof(UInt64)) return DbType.UInt64;
      if (type == typeof(float)) return DbType.Single;
      if (type == typeof(Guid)) return DbType.Guid;
      if (type == typeof(SByte)) return DbType.SByte;
      if (type == typeof(Stream)) return DbType.Binary;
      return DbType.Object;
    }

    #endregion

    #region Dispose

    public void Dispose() {

    }

    #endregion





  }
}
